import socket from '@ohos.net.socket';
import hilog from '@ohos.hilog';
import { Http } from './Http';
import {Response} from "./model/Response"
import Request from './model/Request';
import { Logger } from './utils/Logger';
import Protocol from './protocols/Protocol';
import http from '@ohos.net.http';
import { Utils } from './utils/Utils';
import { Dns } from './Dns';
import { RouteSelector } from './connnection/RouteSelector';
import connection from '@ohos.net.connection';
import { DnsSystem } from './dns/DnsSystem';

export default class httpplus {
  private dns: Dns = new DnsSystem();             // DNS 信息
  routeSelector: RouteSelector; // 路由选择器
  // parsedUrl, userRequest.url.getUrl(), userRequest,
  public execute(userRequest:Request):Promise<Response>{
    // 创建 HTTP 请求实例
    let httpRequest = Http.createHttp();
    // 返回一个 Promise，用于处理 HTTP 请求
    return new Promise<Response>( async (resolve, reject) => {
      let body = userRequest.body;
      var parsedUrl: string = userRequest.url.getUrl();
      let hostOrIp = Utils.getDomainOrIp(parsedUrl)
      let regexp = new RegExp("(\\d*\\.){3}\\d*")
      let isIPv6 = Utils.isIPv6(hostOrIp)
      let isIp = regexp.test(hostOrIp)

      // 构建请求头部
      let headers = body ? Object.assign(userRequest.headers, body.mimes) : Object.assign({}, userRequest.headers);
      // 构建请求选项
      let options = {
        method: userRequest.method,
        header: headers,
        usingProtocol: (userRequest.protocol == http.HttpProtocol.HTTP2) ? http.HttpProtocol.HTTP2 : http.HttpProtocol.HTTP1_1
      };

      // 如果不是 IP 或不是 IPv6
      if (!isIp || !isIPv6) {
        // 如果路由选择器未定义
        if (!!!this.routeSelector) {
          // 如果 DNS 已定义
          if (!!this.dns) {
            // 使用 DNS 查找主机的 IP 地址
            await this.dns.lookup(hostOrIp).then((netAddress) => {
              // 如果未找到网络地址
              if (!!!netAddress) {
                new Error("dns parser not available ip");
                return;
              }
              // 将网络地址去重
              let addressArray: Array<connection.NetAddress> = Utils.arrayUnrepeated(netAddress);
              // 如果第一个地址是 IPv6 地址
              if (Utils.isIPv6(addressArray[0].address)) {
                let ipv4Address: Array<connection.NetAddress> = [];
                let ipv6Address: Array<connection.NetAddress> = [];
                for (var i = 0; i < addressArray.length; i++) {
                  if (Utils.isIPv6(addressArray[i].address)) {
                    ipv6Address.push(addressArray[i]);
                  } else {
                    ipv4Address.push(addressArray[i]);
                  }
                }
                addressArray = [];
                // 将 IPv4 和 IPv6 地址组合在一起
                addressArray = addressArray.concat(ipv4Address).concat(ipv6Address);
              }
              // 初始化路由选择器并重置下一个网络地址
              this.routeSelector = new RouteSelector(this.dns);
              this.routeSelector.resetNextInetSocketAddress(addressArray);
              // 替换请求中的主机地址为路由选择器的下一个地址
              parsedUrl = parsedUrl.replace(hostOrIp, this.routeSelector.next().add.uriHost);
            });
          }
        } else {
          // 如果路由选择器已定义且还有下一个路由
          if (this.routeSelector.hasNextRoute()) {
            // 替换请求中的主机地址为路由选择器的下一个地址
            parsedUrl = parsedUrl.replace(hostOrIp, this.routeSelector.next().add.uriHost);
          }
        }
      }
      // 如果有请求参数，将其添加到 URL 中
      if (null != userRequest.params) {
        options['params'] = userRequest.params;
        let isbegin = true;
        Object.keys(userRequest.params).forEach(function (key) {
          Logger.info('Params key - ' + key + ', value - '
            + userRequest.params[key].toString());
          parsedUrl = parsedUrl.toString().concat(isbegin ? '?' : '&');
          parsedUrl = parsedUrl.concat(key).concat('=').concat(userRequest.params[key].toString());
          isbegin = false;
        });
      }
      // 如果有客户端信息，将连接超时和读取超时添加到选项中
      let client = userRequest.client;
      if (client) {
        if (null != client.connectionTimeout) {
          options['connectTimeout'] = client.connectionTimeout;
          Logger.info('CallServerInterceptor : connectionTimeout:' + client.connectionTimeout);
        }
        if (null != client.readTimeout) {
          options['readTimeout'] = client.readTimeout;
          Logger.info('CallServerInterceptor : readTimeout:' + client.readTimeout);
        }
      }
      // 如果请求体存在并包含内容，将内容添加到选项中
      if (body && null != body.content) {
        options['extraData'] = body.content;
      }
      // parsedUrl, userRequest.url.getUrl(), userRequest
      httpRequest.request(parsedUrl, userRequest.url.getUrl(), userRequest, options, (err, data) => {
        if (!err) {
          // 请求成功，构建响应对象并解析响应数据
          const response = new Response().newBuilder()
            .setRequest(userRequest)
            .setBody(JSON.stringify(data.result))
            .setSentRequestAtMillis(3000)
            .setReceivedResponseAtMillis(new Date().getTime())
            .setHeader(JSON.stringify(data.header))
            .setProtocol(Protocol.HTTP_1_1)
            .setCode(data.responseCode)
            .build();
          resolve(response);
        } else {
          // 请求失败，记录错误日志并拒绝 Promise
          hilog.info(0x0001, "CallServerInterceptor err", JSON.stringify(err));
          reject(err);
        }
        httpRequest.destroy();
      });
    });
  }
}